package org.gdstash.ui.font;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class FieldListener implements DocumentListener {
    private JList list;
    private JTextField textField;
    private ListModel model;
    private SelectionListener selectionListener;

    public void setList(final JList list) {
        this.list = list;
    }

    public void setTextField(final JTextField textField) {
        this.textField = textField;
    }

    public void setModel(final ListModel model) {
        this.model = model;
    }

    public void setSelectionListener(final SelectionListener selectionListener) {
        this.selectionListener = selectionListener;
    }

    @Override
    public void changedUpdate(final DocumentEvent event) {
    }

    @Override
    public void insertUpdate(final DocumentEvent event) {
        this.setListSelection(event);
    }

    @Override
    public void removeUpdate(final DocumentEvent event) {
        this.setListSelection(event);
    }

    private void setListSelection(final DocumentEvent event) {
        final Document document = this.textField.getDocument();
        try {
            final String s = document.getText(0, document.getLength());
            if (s.equals("")) {
                this.list.clearSelection();
                this.list.ensureIndexIsVisible(0);
            } else {
                final ComparisonResult result = this.searchModel(s);
                this.list.removeListSelectionListener(this.selectionListener);
                this.list.ensureIndexIsVisible(this.model.getSize() - 1);
                if (result.isExactMatch()) {
                    this.list.setSelectedIndex(result.getListIndex());
                } else {
                    this.list.clearSelection();
                    this.list.ensureIndexIsVisible(result.getListIndex());
                }
                this.list.addListSelectionListener(this.selectionListener);
            }
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    private ComparisonResult searchModel(final String searchTerm) {
        for (int i = 0; i < this.model.getSize(); ++i) {
            final Object object = this.model.getElementAt(i);
            final String s = object.toString().toLowerCase();
            final String t = searchTerm.toLowerCase();
            if (s.equals(t)) {
                return new ComparisonResult(i, true);
            }
            if (s.startsWith(t)) {
                return new ComparisonResult(i, false);
            }
        }
        return new ComparisonResult(0, false);
    }
}
